package com.le.dub.service.impl;

import cn.hutool.core.util.StrUtil;
import com.le.dub.common.BusinessRuntimeException;
import com.le.dub.conf.RedisKey;
import com.le.dub.mobile.DubRecord;
import com.le.dub.mobile.DubRole;
import com.le.dub.mobile.bo.TextToSpeechBO;
import com.le.dub.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
@Slf4j
@Service
public class AppVoiceServiceImpl implements IAppVoiceService {
    @Resource
    private IUserService userService;
    @Resource
    private IDubRecordService dubRecordService;
    @Resource
    private RedisTemplate template;
    @Resource
    private IVoiceService cosyVoiceService;
    @Resource
    private IDubRoleService dubRoleService;
    @Resource
    private IFileService fileService;

    @Override
    public DubRecord submitVoice(TextToSpeechBO speechBO) {
        String key = RedisKey.submitVoice + speechBO.getUserId();

        if (StrUtil.isEmpty(speechBO.getText())) {
            throw new BusinessRuntimeException("500", "请输入需要生成的文本");

        }

        //分别锁控制 ，让用户每次只能执行一个任务
        if (!template.opsForValue().setIfAbsent(key, key)) {
            throw new BusinessRuntimeException("500", "当前正在生成语音，请处理完后再次提交");
        }
        DubRecord dubRecord =null;
        try {
            Integer characterNum = StrUtil.byteLength(speechBO.getText(), Charset.forName("GBK"));
            //校验是否可以 使用语音服务
            userService.checkUserVoice(speechBO.getUserId(), characterNum);


            //创建语音生成生成记录
              dubRecord = new DubRecord();
            dubRecord.setText(speechBO.getText());
            dubRecord.setRoleId(speechBO.getRoleId());
            dubRecord.setCreateTime(new Date());
            dubRecord.setGenerateStatus(1);
            dubRecord.setCharacterNum(characterNum);
            dubRecord.setUserId(speechBO.getUserId());
            dubRecordService.save(dubRecord);
            template.opsForList().rightPush(RedisKey.voiceList, dubRecord.getId().toString());

        } catch (BusinessRuntimeException e) {
            //删除用户任务锁
            template.delete(key);
            throw new BusinessRuntimeException(e.getCode(), e.getMsg());

        }
        return dubRecord;

    }

    /**
     * 扣除用户费用并生成语音文件
     * @param dubRecord
     * @return
     */
    @Transactional
    @Override
    public String  executeVoice(DubRecord dubRecord)throws  BusinessRuntimeException {

        String path = null;

            DubRole dubRole = dubRoleService.getById(dubRecord.getRoleId());
            //扣除用户费用
            userService.deductUserEnergy(dubRecord.getUserId(), dubRecord.getCharacterNum());
            //执行阿里云文字转语音服务

            byte[] result = cosyVoiceService.textToSpeech(dubRecord.getText(), dubRole.getCosyVoiceName());
            path = fileService.upload(result, "mp3", 2);

        return path;

     }


    @Override
    public DubRecord dubRecordById(Long dubRecordId) {
        return this.dubRecordService.getById(dubRecordId);
    }

    @Override
    public List<DubRecord> dubRecordListByUser(Long userId) {
        return dubRecordService.lambdaQuery().eq(DubRecord::getUserId,userId).list();
    }


    public static void main(String[] args) {
        String str = "a。";
        Integer characterNum = StrUtil.byteLength(str, Charset.forName("GBK"));
        System.out.println(characterNum);
        System.out.println(str.getBytes(StandardCharsets.UTF_8).length);

    }
}
